﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;


namespace simDC
{
    public partial class Simulator : Form
    {
        //Parser parser = null;
        public static ManualResetEvent updateArchitecture = new ManualResetEvent(false);

        public static ManualResetEvent updateMemory = new ManualResetEvent(false); 

        Microcode microF = new Microcode();
        
        Code codeF = new Code();
        
        Output outF = new Output();
        archForm archF = new archForm();
        Memory Mem = new Memory();
       
        Compiler compiler = null;
        BGC Bgc = null;

        MicrocodeCodif micorC = null;

  
        
        
        public Simulator()
        {
            Bgc = new BGC(microF.listMicroCode, archF.instText);
            micorC = new MicrocodeCodif();
            InitializeComponent();
            archF.MdiParent = this;
            codeF.MdiParent = this;
            outF.MdiParent = this;
            Mem.MdiParent = this;
            microF.MdiParent = this;

            fileOpen.CheckFileExists = true;
            fileOpen.InitialDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory()));
            fileOpen.Filter = "All files (*.*)|*.*|Text Files (*.txt)|*.TXT|Assembly Files (*.asm)|*.ASM|Binary Files (*.bin)|*.BIN|CSV Files (*.csv)|*.CSV";
            loadBinaryFileToolStripMenuItem.Enabled = false;
            stepToolStripMenuItem.Enabled = false;
            runToolStripMenuItem.Enabled = false;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void compileItem_Click(object sender, EventArgs e)
        {
            outF.outRTB.Text = "";
            compiler = new Compiler(new Parser(codeF.editorRTB, outF.outRTB), outF.outRTB);
            loadBinaryFileToolStripMenuItem.Enabled = true;
           
            
        }

        private void output_TextChanged(object sender, EventArgs e)
        {

        }

        

        private void architectureToolStripMenuItem_Click(object sender, EventArgs e)
        {         
           archF.Show();            
        }

        private void codeEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            codeF.Show();
        }

        private void outputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            outF.Show();
        }

        private void loadMicrocodeToolStripMenuItem_Click(object sender, EventArgs e)
        {           
            
            if (fileOpen.ShowDialog() == DialogResult.OK)
            {
                int a = Bgc.LoadMicrocode(fileOpen.FileName);
                if (a == 1)
                {
                    MenuItemloadMicrocode.Enabled = false;
                    loadBinaryFileToolStripMenuItem.Enabled = true;
                    
                }
                else MessageBox.Show("Try again!", "Error",
                   MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

           
        }

        private void stepToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bgc.ExecuteStep(archF.microCode);
        }

        private void runToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bgc.Run(archF.microCode);
        }
       
        private void memoryToolStripMenuItem_Click(object sender, EventArgs e)
        {          
                Mem.Show();
           
        }

        private void loadBinaryFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
           
        }

        private void loadFileItem_Click(object sender, EventArgs e)
        {
            if (fileOpen.ShowDialog() == DialogResult.OK)
            {
                codeF.editorRTB.Clear();
                string [] buffer = System.IO.File.ReadAllLines(fileOpen.FileName);
                foreach (string line in buffer)
                    codeF.editorRTB.AppendText("\n"+line);
                loadFileItem.Enabled = false;
            }

           
            
        }

        private void currentToolStripMenuItem_Click(object sender, EventArgs e)
        {
          
            fileOpen.InitialDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory()));
            if (MenuItemloadMicrocode.Enabled == false && compiler != null)
            {
               compiler.loadProgram();
                stepToolStripMenuItem.Enabled = true;
                runToolStripMenuItem.Enabled = true;
                loadBinaryFileToolStripMenuItem.Enabled = false;
                Bgc.LoadInstructionText();
            }
            else MessageBox.Show("Load Microcode first and compile !", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);

        }

        private void fromFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            string str = null;
            if (MenuItemloadMicrocode.Enabled == false && compiler != null)
            {

                if (fileOpen.ShowDialog() == DialogResult.OK)
                {
                    if (fileOpen.FileName != null)
                    {
                        str = fileOpen.FileName;
                       compiler.loadProgram(str);
                        loadBinaryFileToolStripMenuItem.Enabled = false;
                        stepToolStripMenuItem.Enabled = true;
                        runToolStripMenuItem.Enabled = true;
                        Bgc.LoadInstructionText();
                    }
                }
                
            }
            else MessageBox.Show("Load Microcode first and compile !", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            
        }
        public void ResetAll() 
        {
            loadBinaryFileToolStripMenuItem.Enabled = true;
            stepToolStripMenuItem.Enabled = false;
            runToolStripMenuItem.Enabled = false;
            loadBinaryFileToolStripMenuItem.Enabled = false;
            Bgc.Reset();
            compiler.Reset();
            

        }

        private void resetAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ResetAll();
            
        }

        private void Simulator_FormClosing(object sender, FormClosingEventArgs e)
        {
            Mem.localThred.Abort();
            archF.threadShow.Abort();
            updateMemory.Dispose();
            updateArchitecture.Dispose();

            codeF.Close();
            outF.Close();
            Mem.Close();
            archF.Close();
           
        }

        private void allToolStripMenuItem_Click(object sender, EventArgs e)
        {
            archF.Show();
            codeF.Show();
            outF.Show();
            Mem.Show();         
            microF.Show();
            this.LayoutMdi(System.Windows.Forms.MdiLayout.TileVertical);
        }

        private void microcodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            microF.Show();
        }

        private void Simulator_FormClosed(object sender, FormClosedEventArgs e)
        {
            
            //exit(0);
        }

        private void Simulator_Load(object sender, EventArgs e)
        {
                
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            outF.outRTB.Text = "";
            compiler = new Compiler(new Parser(codeF.editorRTB, outF.outRTB), outF.outRTB);
            loadBinaryFileToolStripMenuItem.Enabled = true;
           
        }

        private void buildToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void loadExecuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fileOpen.ShowDialog() == DialogResult.OK)
            {
                codeF.editorRTB.Clear();
                string[] buffer = System.IO.File.ReadAllLines(fileOpen.FileName);
                foreach (string line in buffer)
                    codeF.editorRTB.AppendText("\n" + line);
                loadFileItem.Enabled = false;
            }
        }

        private void loadExecutableFromFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fileOpen.ShowDialog() == DialogResult.OK)
            {
                int a = Bgc.LoadMicrocode(fileOpen.FileName);
                if (a == 1)
                {
                    MenuItemloadMicrocode.Enabled = false;
                    loadBinaryFileToolStripMenuItem.Enabled = true;

                }
                else MessageBox.Show("Try again!", "Error",
                   MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            Bgc.Run(archF.microCode);
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            Bgc.ExecuteStep(archF.microCode);
        }
        
    }
}
